package at.meder.evaluation.editors;



import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ListViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.ISaveablePart;
import org.eclipse.ui.ISaveablePart2;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.part.EditorPart;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import at.meder.evaluation.View;
import at.meder.evaluation.model.Criterion;
import at.meder.evaluation.model.CriteriaProvider;

public class SoapHeaderEditor extends EditorPart implements ISaveablePart{

	public static final String ID = "at.meder.evaluation.editor.SoapHeaderEditor";
	
	private Criterion criterion;
	private EditorInput input;
	private boolean dirty=false;

	
	private Text metric1;
	private Text metric2;
	private Text metric3;
	
	
	public SoapHeaderEditor() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void doSave(IProgressMonitor monitor) {
		
		criterion.setMetric1(metric1.getText());
		criterion.setMetric2(metric2.getText());
		criterion.setMetric3(metric3.getText());
		//connection.setPort(port.getText());
		
		evaluateSaved();
		
		
		View view = (View) getSite().getPage().findView(View.ID);
		ListViewer viewer = view.getViewer();
		viewer.refresh();
		dirty = false;
	    firePropertyChange(ISaveablePart.PROP_DIRTY);
		

	}
	
	private void displayLevel() {
		MessageDialog.openInformation(getSite().getShell(), "Evaluation level", "Level: "+criterion.getLevel());
	}

	@Override
	public void doSaveAs() {
		// TODO Auto-generated method stub

	}
	
	

	@Override
	public void dispose() {
		// TODO Auto-generated method stub
		super.dispose();
		displayLevel();
	}

	@Override
	public void init(IEditorSite site, IEditorInput input)
			throws PartInitException {
		
		if (!(input instanceof EditorInput)) {
			throw new RuntimeException("Wrong input");
		}

		EditorInput new_name = (EditorInput) input;
		this.input = (EditorInput) input;
		setSite(site);
		setInput(input);
		criterion = CriteriaProvider.getInstance().getCriterionById(this.input.getId());
		setPartName(Messages.CostsEditor_2 + criterion.getName());


	}

	@Override
	public boolean isDirty() {
		return dirty;
	}

	@Override
	public boolean isSaveAsAllowed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void createPartControl(Composite parent) {
		GridLayout layout = new GridLayout();
		layout.numColumns = 1;
		parent.setLayout(layout);
		
		Label label1 = new Label(parent, SWT.BORDER);
		label1.setText(criterion.getMetric1_name());
		
			
		
		metric1 = new Text(parent, SWT.MULTI | SWT.WRAP|SWT.V_SCROLL);
		metric1.setSize(50, 50);
		metric1.setText(criterion.getMetric1());
		GridData gridData = new GridData(SWT.FILL, SWT.BEGINNING, true, false,5,5);
		gridData =new GridData(GridData.FILL_BOTH);
		//gridData.minimumHeight=5;
		//gridData.verticalSpan=5;
		metric1.setLayoutData(gridData);
		
		
		
		Label label2 = new Label(parent, SWT.BORDER);
		label2.setText(criterion.getMetric2_name());
		metric2 = new Text(parent, SWT.MULTI | SWT.WRAP |SWT.V_SCROLL);
		metric2.setSize(50, 50);
		metric2.setText(criterion.getMetric2());
		metric2.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		Label label3 = new Label(parent, SWT.BORDER);
		label3.setText(criterion.getMetric3_name());
		metric3 = new Text(parent, SWT.MULTI | SWT.WRAP |SWT.V_SCROLL);
		metric3.setSize(50, 50);
		metric3.setText(criterion.getMetric3());
		metric3.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		
		
		
		Button button2 = new Button(parent, SWT.PUSH);
		button2.setText(Messages.CostsEditor_3);
		button2.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				
				
				//ISelection selection = getSite().getWorkbenchWindow().getSelectionService().getSelection(View.ID);
				View view = (View) getSite().getPage().findView(View.ID);
				ListViewer viewer = view.getViewer();
				evaluate();
				
				viewer.refresh();
		}

			
			
		});
				
				
				
				
				

		
		metric1.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                setDirty(true);
            }
        });
		metric2.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                setDirty(true);
            }
        });
		metric3.addModifyListener(new ModifyListener() {
            public void modifyText(ModifyEvent e) {
                setDirty(true);
            }
        });
		
		

	}

	@Override
	public void setFocus() {
		// TODO Auto-generated method stub

	}

	public void setDirty(boolean dirty) {
		this.dirty = dirty;
		firePropertyChange(IEditorPart.PROP_DIRTY);

	}
	private void evaluate() {
		try{
			if(metric1.getText()!=""){
				int searchHeaderElements = searchHeaderElements(metric1.getText());
				if(searchHeaderElements==0){
					criterion.setLevel(1);
					if(metric2.getText()!=""){
						int searchHeaderElements2 = searchHeaderElements(metric2.getText());
						if(searchHeaderElements2==1){
							if(metric3.getText()!=""){
								int searchHeaderElements3 = searchHeaderElementsBlocks(metric3.getText());
								
								if(searchHeaderElements3>0)
								{
									criterion.setLevel(2);
								}
								else{
									criterion.setLevel(1);
								}
							}
							
						}
						
					}
				}
				else{
					criterion.setLevel(0);
				}
			}
			else{
				criterion.setLevel(0);
			}
		}
		catch(NumberFormatException ex){
			criterion.setLevel(0);
		}
		displayLevel();
	}
	
	
	private void evaluateSaved() {
		try{
			if(criterion.getMetric1()!=Messages.CostsEditor_4){
				criterion.setLevel(1);
			}
			else{
				criterion.setLevel(0);
			}
		}
		catch(NumberFormatException ex){
			criterion.setLevel(0);
		}
		displayLevel();
	}
	
	private int searchHeaderElements(String soap){
		int count=-1;
		DocumentBuilderFactory docFactory = null;  
		DocumentBuilder docBuilder = null;  
		Document document = null;  
		try {  
		    docFactory = DocumentBuilderFactory.newInstance();  
		    docBuilder = docFactory.newDocumentBuilder();  
		    InputStream input = new ByteArrayInputStream(soap.getBytes());
		    document = docBuilder.parse(input);
		    
		    SOAPMessage createMessage = MessageFactory.newInstance().createMessage(null, input);
		   
		    
		    NodeList elementsByTagNameNS = document.getElementsByTagNameNS("*", "*");
		    for(int i =0;i<elementsByTagNameNS.getLength();i++)
		    {
		    	Node node = elementsByTagNameNS.item(i);
		    	String nodeName = node.getNodeName();
		    	String[] split = nodeName.split(":");
		    	String nspace="";
		    	if(split.length>1){
		    		nspace = split[0];
		    	}
		    	if(nodeName.toLowerCase().indexOf("envelope")>0)
		    	{
		    		count=0;
			    	NamedNodeMap attributes = node.getAttributes();
			    	for(int j=0;j<attributes.getLength();j++)
			    	{
			    		
			    		Node item = attributes.item(j);
			    		//System.out.println(item.getNodeName());
			    		String namespace = "xmlns:"+nspace;
			    		
			    		if(item.getNodeName().indexOf(namespace)>=0){
			    			String soapenvelopenamespace = item.getNodeValue();
			    			
			    			boolean issoap=false;
			    			//SOAP 1.2
			    			if(soapenvelopenamespace.indexOf("http://www.w3.org/2001/12/soap-envelope")>=0){
			    				issoap=true;
			    			}
			    			//SOAP 1.1
		    				if(soapenvelopenamespace.indexOf("http://schemas.xmlsoap.org/soap/envelope/")>=0){
		    					issoap=true;
			    			}
		    				//SOAP 1.2
		    				if(soapenvelopenamespace.indexOf("http://www.w3.org/2003/05/soap-envelope")>=0){
		    					issoap=true;
			    			}
			    			if(issoap){
				    			NodeList childNodes = node.getChildNodes();
				    			for(int x=0;x<childNodes.getLength();x++){
				    				
				    				Node item2 = childNodes.item(x);
				    				String nodeName2 = item2.getNodeName();
				    				if(nodeName2.toLowerCase().indexOf("header")>0)
				    		    	{
				    					
				    					count++;	
				    					
				    					
				    					NamedNodeMap attributes2 = item2.getAttributes();
				    			    	for(int y=0;y<attributes2.getLength();y++)
				    			    	{
				    			    		
				    			    		Node item3 = attributes.item(y);
				    			    		System.out.println(item.getNodeName());
				    			    	}
				    		    	}
				    				System.out.println(item2.getNodeName());
				    				
				    			}
			    				
			    			}
			    			System.out.println(issoap);
			    		}
			    		
			    	}
			    	
			    	//System.out.println(node.getNodeName());
			    	//System.out.println(node.getPrefix());
			    }
		    	
		    }
		    //System.out.println(elementsByTagNameNS.getLength());
		    
		}
		catch(IOException e){
			e.printStackTrace();
			return -1;
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (SOAPException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
		
		
		return count;
	}
	private int searchHeaderElementsBlocks(String soap){
		int count=0;
		DocumentBuilderFactory docFactory = null;  
		DocumentBuilder docBuilder = null;  
		Document document = null;  
		try {  
		    docFactory = DocumentBuilderFactory.newInstance();  
		    docBuilder = docFactory.newDocumentBuilder();  
		    InputStream input = new ByteArrayInputStream(soap.getBytes());
		    document = docBuilder.parse(input);
		    
		    SOAPMessage createMessage = MessageFactory.newInstance().createMessage(null, input);
		   
		    
		    NodeList elementsByTagNameNS = document.getElementsByTagNameNS("*", "*");
		    for(int i =0;i<elementsByTagNameNS.getLength();i++)
		    {
		    	Node node = elementsByTagNameNS.item(i);
		    	String nodeName = node.getNodeName();
		    	String[] split = nodeName.split(":");
		    	String nspace="";
		    	if(split.length>1){
		    		nspace = split[0];
		    	}
		    	if(nodeName.toLowerCase().indexOf("envelope")>0)
		    	{
			    	NamedNodeMap attributes = node.getAttributes();
			    	for(int j=0;j<attributes.getLength();j++)
			    	{
			    		
			    		Node item = attributes.item(j);
			    		//System.out.println(item.getNodeName());
			    		String namespace = "xmlns:"+nspace;
			    		
			    		if(item.getNodeName().indexOf(namespace)>=0){
			    			String soapenvelopenamespace = item.getNodeValue();
			    			
			    			boolean issoap=false;
			    			//SOAP 1.1
			    			if(soapenvelopenamespace.indexOf("http://www.w3.org/2001/12/soap-envelope")>=0){
			    				issoap=true;
			    			}
			    			//SOAP 1.1
		    				if(soapenvelopenamespace.indexOf("http://schemas.xmlsoap.org/soap/envelope/")>=0){
		    					issoap=true;
			    			}
		    				//SOAP 1.2
		    				if(soapenvelopenamespace.indexOf("http://www.w3.org/2003/05/soap-envelope")>=0){
		    					issoap=true;
			    			}
		    				
		    				
			    			if(issoap){
				    			NodeList childNodes = node.getChildNodes();
				    			for(int x=0;x<childNodes.getLength();x++){
				    				
				    				Node item2 = childNodes.item(x);
				    				String nodeName2 = item2.getNodeName();
				    				if(nodeName2.toLowerCase().indexOf("header")>0)
				    		    	{
				    					
				    					NodeList childNodes2 = item2.getChildNodes();
				    					
				    					count+=childNodes2.getLength();
				    					/*NamedNodeMap attributes2 = item2.getAttributes();
				    			    	for(int y=0;y<attributes2.getLength();y++)
				    			    	{
				    			    		
				    			    		Node item3 = attributes.item(y);
				    			    		System.out.println(item.getNodeName());
				    			    	}*/
				    		    	}
				    				System.out.println(item2.getNodeName());
				    				
				    			}
			    				
			    			}
			    			System.out.println(issoap);
			    		}
			    		
			    	}
			    	
			    	//System.out.println(node.getNodeName());
			    	//System.out.println(node.getPrefix());
			    }
		    }
		    //System.out.println(elementsByTagNameNS.getLength());
		    
		}
		catch(IOException e){
			e.printStackTrace();
			return -1;
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		} catch (SOAPException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return -1;
		}
		
		
		return count;
	}

	
	
	
	
}
